/*
 * Copyright (C) 2012  Romain DUBOIS
 * 
 * This file is part of NeMoS - Network and Modular Software
 * 
 * NeMoS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * NeMoS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with NeMoS.  If not, see <http://www.gnu.org/licenses/>.
 */
package nemos.launch.internal;

import nemos.launch.progress.IStatus;

import org.osgi.framework.Bundle;

/**
 * StatusImpl : The status implementation.
 * 
 * @author Romain DUBOIS
 */
public class StatusImpl implements IStatus {

    /** The current start level */
    private int mCurrentLevel;

    /** The number of bundles installed in this level */
    private int mInstalledBundles;

    /** The last action timestamp */
    private long mLastAction;

    /** The last started bundle */
    private Bundle mLastStartedBundle;

    /** The level start timestamp */
    private long mLevelStart;

    /** The launch start timestamp */
    private final long mStart;

    /** The number of bundles started in this level */
    private int mStartedBundles;

    /** The target start level */
    private final int mTargetLevel;

    /**
     * Constructor
     * 
     * @param pTargetLevel
     *            The target start level
     */
    public StatusImpl(final int pTargetLevel) {
        super();
        mCurrentLevel = 0;
        mTargetLevel = pTargetLevel;
        mStart = System.currentTimeMillis();
        mLevelStart = mStart;
        mLastAction = mStart;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.launch.progress.IStatus#getBundlesToStart()
     */
    @Override
    public int getBundlesToStart() {
        return mInstalledBundles;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.launch.progress.IStatus#getCurrentLevel()
     */
    @Override
    public int getCurrentLevel() {
        return mCurrentLevel;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.launch.progress.IStatus#getLastStartedBundle()
     */
    @Override
    public Bundle getLastStartedBundle() {
        return mLastStartedBundle;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.launch.progress.IStatus#getSpentTime()
     */
    @Override
    public long getSpentTime() {
        return mLastAction - mStart;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.launch.progress.IStatus#getSpentTimeInLevel()
     */
    @Override
    public long getSpentTimeInLevel() {
        return mLastAction - mLevelStart;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.launch.progress.IStatus#getStartedBundles()
     */
    @Override
    public int getStartedBundles() {
        return mStartedBundles;
    }

    /**
     * {@inheritDoc}
     * 
     * @see nemos.launch.progress.IStatus#getTargetLevel()
     */
    @Override
    public int getTargetLevel() {
        return mTargetLevel;
    }

    /**
     * A bundle has been started.
     * 
     * @param pBundle
     *            The installed bundle
     */
    public void startBundle(final Bundle pBundle) {
        mLastStartedBundle = pBundle;
        mLastAction = System.currentTimeMillis();
        mStartedBundles++;
    }

    /**
     * Change the current start level.
     * 
     * @param pCurrentLevel
     *            the currentLevel to set
     * @param pBundles
     *            The number of bundles to start in the new level
     * @return The time spent in the previous level
     */
    long changeLevel(final int pCurrentLevel, final int pBundles) {
        mCurrentLevel = pCurrentLevel;
        mInstalledBundles = pBundles;
        mLastStartedBundle = null;
        mStartedBundles = 0;
        final long lLastLevelStart = mLevelStart;
        mLevelStart = System.currentTimeMillis();
        mLastAction = mLevelStart;
        return mLastAction - lLastLevelStart;
    }
}
